<!doctype html>














<!-- `site.alt_lang` can specify a language different from the UI -->
<html lang="en" 
  
>
  <!-- The Head -->

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
  <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta
    name="viewport"
    content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
  >

  

  

  
    <!-- Begin Jekyll SEO tag v2.8.0 -->
<meta name="generator" content="Jekyll v4.3.2" />
<meta property="og:title" content="Input-Output Memory Management Unit" />
<meta name="author" content="Chunsheng Luo" />
<meta property="og:locale" content="en" />
<meta name="description" content="1 2 Intel IOMMU Introduction https://kernelgo.org/intel_iommu.html https://blog.csdn.net/21cnbao/article/details/106293976" />
<meta property="og:description" content="1 2 Intel IOMMU Introduction https://kernelgo.org/intel_iommu.html https://blog.csdn.net/21cnbao/article/details/106293976" />
<link rel="canonical" href="https://luochenglcs.github.io/posts/linux-iommu/" />
<meta property="og:url" content="https://luochenglcs.github.io/posts/linux-iommu/" />
<meta property="og:site_name" content="Cheng Luo" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-02-20T00:00:00+00:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Input-Output Memory Management Unit" />
<meta name="twitter:site" content="@luochenglcs" />
<meta name="twitter:creator" content="@Chunsheng Luo" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Chunsheng Luo","url":"https://github.com/luochenglcs"},"dateModified":"2023-08-08T09:05:07+00:00","datePublished":"2023-02-20T00:00:00+00:00","description":"1 2 Intel IOMMU Introduction https://kernelgo.org/intel_iommu.html https://blog.csdn.net/21cnbao/article/details/106293976","headline":"Input-Output Memory Management Unit","mainEntityOfPage":{"@type":"WebPage","@id":"https://luochenglcs.github.io/posts/linux-iommu/"},"url":"https://luochenglcs.github.io/posts/linux-iommu/"}</script>
<!-- End Jekyll SEO tag -->

  

  <title>Input-Output Memory Management Unit | Cheng Luo
  </title>

  <!--
  The Favicons for Web, Android, Microsoft, and iOS (iPhone and iPad) Apps
  Generated by: https://realfavicongenerator.net/
-->



<link rel="apple-touch-icon" sizes="180x180" href="/assets/img/favicons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicons/favicon-16x16.png">
<link rel="manifest" href="/assets/img/favicons/site.webmanifest">
<link rel="shortcut icon" href="/assets/img/favicons/favicon.ico">
<meta name="apple-mobile-web-app-title" content="Cheng Luo">
<meta name="application-name" content="Cheng Luo">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-config" content="/assets/img/favicons/browserconfig.xml">
<meta name="theme-color" content="#ffffff">


  
    
      <link rel="preconnect" href="https://fonts.googleapis.com" >
      <link rel="dns-prefetch" href="https://fonts.googleapis.com" >
    
      <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
      <link rel="dns-prefetch" href="https://fonts.gstatic.com" crossorigin>
    
      <link rel="preconnect" href="https://fonts.googleapis.com" >
      <link rel="dns-prefetch" href="https://fonts.googleapis.com" >
    
      <link rel="preconnect" href="https://cdn.jsdelivr.net" >
      <link rel="dns-prefetch" href="https://cdn.jsdelivr.net" >
    

    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;700;900&display=swap">
  

  <!-- GA -->
  

  <!-- Bootstrap -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">

  <!-- Font Awesome -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css">

  <link rel="stylesheet" href="/assets/css/style.css">

  
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tocbot@4.21.0/dist/tocbot.min.css">
  

  
    <!-- Manific Popup -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css">
  

  <!-- JavaScript -->

  
    <!-- Switch the mode between dark and light. -->

<script type="text/javascript">
  class ModeToggle {
    static get MODE_KEY() {
      return 'mode';
    }
    static get MODE_ATTR() {
      return 'data-mode';
    }
    static get DARK_MODE() {
      return 'dark';
    }
    static get LIGHT_MODE() {
      return 'light';
    }
    static get ID() {
      return 'mode-toggle';
    }

    constructor() {
      if (this.hasMode) {
        if (this.isDarkMode) {
          if (!this.isSysDarkPrefer) {
            this.setDark();
          }
        } else {
          if (this.isSysDarkPrefer) {
            this.setLight();
          }
        }
      }

      let self = this;

      /* always follow the system prefers */
      this.sysDarkPrefers.addEventListener('change', () => {
        if (self.hasMode) {
          if (self.isDarkMode) {
            if (!self.isSysDarkPrefer) {
              self.setDark();
            }
          } else {
            if (self.isSysDarkPrefer) {
              self.setLight();
            }
          }

          self.clearMode();
        }

        self.notify();
      });
    } /* constructor() */

    get sysDarkPrefers() {
      return window.matchMedia('(prefers-color-scheme: dark)');
    }

    get isSysDarkPrefer() {
      return this.sysDarkPrefers.matches;
    }

    get isDarkMode() {
      return this.mode === ModeToggle.DARK_MODE;
    }

    get isLightMode() {
      return this.mode === ModeToggle.LIGHT_MODE;
    }

    get hasMode() {
      return this.mode != null;
    }

    get mode() {
      return sessionStorage.getItem(ModeToggle.MODE_KEY);
    }

    /* get the current mode on screen */
    get modeStatus() {
      if (this.isDarkMode || (!this.hasMode && this.isSysDarkPrefer)) {
        return ModeToggle.DARK_MODE;
      } else {
        return ModeToggle.LIGHT_MODE;
      }
    }

    setDark() {
      document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
      sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
    }

    setLight() {
      document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
      sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
    }

    clearMode() {
      document.documentElement.removeAttribute(ModeToggle.MODE_ATTR);
      sessionStorage.removeItem(ModeToggle.MODE_KEY);
    }

    /* Notify another plugins that the theme mode has changed */
    notify() {
      window.postMessage(
        {
          direction: ModeToggle.ID,
          message: this.modeStatus
        },
        '*'
      );
    }

    flipMode() {
      if (this.hasMode) {
        if (this.isSysDarkPrefer) {
          if (this.isLightMode) {
            this.clearMode();
          } else {
            this.setLight();
          }
        } else {
          if (this.isDarkMode) {
            this.clearMode();
          } else {
            this.setDark();
          }
        }
      } else {
        if (this.isSysDarkPrefer) {
          this.setLight();
        } else {
          this.setDark();
        }
      }

      this.notify();
    } /* flipMode() */
  } /* ModeToggle */

  const modeToggle = new ModeToggle();
</script>

  

  <!-- A placeholder to allow defining custom metadata -->

</head>


  <body>
    <!-- The Side Bar -->

<div id="sidebar" class="d-flex flex-column align-items-end">
  <div class="profile-wrapper">
    <a href="/" id="avatar" class="rounded-circle">
      
        
        <img src="/assets/img/favicons/android-chrome-512x512.png" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
      
    </a>

    <div class="site-title">
      <a href="/">Cheng Luo</a>
    </div>
    <div class="site-subtitle fst-italic">Linux operating system engineer</div>
  </div>
  <!-- .profile-wrapper -->

  <ul class="nav flex-column flex-grow-1 w-100 ps-0">
    <!-- home -->
    <li class="nav-item">
      <a href="/" class="nav-link">
        <i class="fa-fw fas fa-home"></i>
        <span>HOME</span>
      </a>
    </li>
    <!-- the real tabs -->
    
      <li class="nav-item">
        <a href="/categories/" class="nav-link">
          <i class="fa-fw fas fa-stream"></i>
          

          <span>CATEGORIES</span>
        </a>
      </li>
      <!-- .nav-item -->
    
      <li class="nav-item">
        <a href="/tags/" class="nav-link">
          <i class="fa-fw fas fa-tags"></i>
          

          <span>TAGS</span>
        </a>
      </li>
      <!-- .nav-item -->
    
      <li class="nav-item">
        <a href="/archives/" class="nav-link">
          <i class="fa-fw fas fa-archive"></i>
          

          <span>ARCHIVES</span>
        </a>
      </li>
      <!-- .nav-item -->
    
      <li class="nav-item">
        <a href="/about/" class="nav-link">
          <i class="fa-fw fas fa-info-circle"></i>
          

          <span>ABOUT</span>
        </a>
      </li>
      <!-- .nav-item -->
    
  </ul>
  <!-- ul.nav.flex-column -->

  <div class="sidebar-bottom d-flex flex-wrap  align-items-center w-100">
    
      <button class="mode-toggle btn" aria-label="Switch Mode">
        <i class="fas fa-adjust"></i>
      </button>

      
        <span class="icon-border"></span>
      
    

    
      

      
        <a
          href="https://github.com/luochenglcs"
          aria-label="github"
          

          
            target="_blank"
            
          

          

          
            rel="noopener noreferrer"
          
        >
          <i class="fab fa-github"></i>
        </a>
      
    
      

      
    
      

      
        <a
          href="javascript:location.href = 'mailto:' + ['luochunsheng','ustc.edu'].join('@')"
          aria-label="email"
          

          

          

          
        >
          <i class="fas fa-envelope"></i>
        </a>
      
    
  </div>
  <!-- .sidebar-bottom -->
</div>
<!-- #sidebar -->


    <div id="main-wrapper" class="d-flex justify-content-center">
      <div id="main" class="container px-xxl-5">
        <!-- The Top Bar -->

<div id="topbar-wrapper">
  <div
    id="topbar"
    class="container d-flex align-items-center justify-content-between h-100"
  >
    <span id="breadcrumb">
      

      
        
          
            <span>
              <a href="/">
                Home
              </a>
            </span>

          
        
          
        
          
            
              <span>Input-Output Memory Management Unit</span>
            

          
        
      
    </span>
    <!-- endof #breadcrumb -->

    <i id="sidebar-trigger" class="fas fa-bars fa-fw"></i>

    <div id="topbar-title">
      Post
    </div>

    <i id="search-trigger" class="fas fa-search fa-fw"></i>
    <span id="search-wrapper" class="align-items-center">
      <i class="fas fa-search fa-fw"></i>
      <input
        class="form-control"
        id="search-input"
        type="search"
        aria-label="search"
        autocomplete="off"
        placeholder="Search..."
      >
    </span>
    <span id="search-cancel">Cancel</span>
  </div>
</div>

        











<div class="row">
  <!-- core -->
  <div id="core-wrapper" class="col-12 col-lg-11 col-xl-9 pe-xl-4">
    

    <div class="post px-1 px-md-2">
      

      
        
      
        <!-- Refactor the HTML structure -->



<!--
  In order to allow a wide table to scroll horizontally,
  we suround the markdown table with `<div class="table-wrapper">` and `</div>`
-->



<!--
  Fixed kramdown code highlight rendering:
  https://github.com/penibelst/jekyll-compress-html/issues/101
  https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
-->



<!-- Change the icon of checkbox -->


<!-- images -->



  
  

  <!-- CDN URL -->
  

  <!-- Add image path -->
  

  
    
      
      
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  

  



<!-- Add header for code snippets -->



<!-- Create heading anchors -->





  
  

  

  
  

  
    
    

    
      
        
        
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    

    

  

  
  

  
    
    

    
      
        
        
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    

    

  

  
  

  
    
    

    
      
        
        
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    

    

  




<!-- return -->




<h1 data-toc-skip>Input-Output Memory Management Unit</h1>

<div class="post-meta text-muted">
    <!-- published date -->
    <span>
      Posted
      <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class=""
  data-ts="1676851200"
  data-df="ll"
  
    data-bs-toggle="tooltip" data-bs-placement="bottom"
  
>
  Feb 20, 2023
</em>

    </span>

    <!-- lastmod date -->
    
    <span>
      Updated
      <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class=""
  data-ts="1691485507"
  data-df="ll"
  
    data-bs-toggle="tooltip" data-bs-placement="bottom"
  
>
  Aug  8, 2023
</em>

    </span>
    

  

  <div class="d-flex justify-content-between">
    <!-- author(s) -->
    <span>
      

      By

      <em>
      
        
          <a href="https://github.com/luochenglcs">Chunsheng Luo</a>
          
        
      
      </em>
    </span>

    <div>
      <!-- read time -->
      <!-- Calculate the post's reading time, and display the word count in tooltip -->



<!-- words per minute -->










<!-- return element -->
<span
  class="readtime"
  data-bs-toggle="tooltip"
  data-bs-placement="bottom"
  title="3553 words"
>
  <em>19 min</em> read</span>

    </div>

  </div> <!-- .d-flex -->

</div> <!-- .post-meta -->
<div class="post-content">
  <div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="n">Intel</span> <span class="n">IOMMU</span> <span class="n">Introduction</span> <span class="n">https</span><span class="o">:</span><span class="c1">//kernelgo.org/intel_iommu.html</span>
<span class="n">https</span><span class="o">:</span><span class="c1">//blog.csdn.net/21cnbao/article/details/106293976</span>
</pre></td></tr></tbody></table></code></div></div>

<p>对于Intel的硬件辅助虚拟化方案而言核心的两大技术分别是VT-x和VT-d。 其中VT-x中主要引入了non-root模式(VMCS)以及EPT页表等技术，主要关注于vCPU的虚拟化和内存虚拟化。 而VT-d的引入则是重点关注设备直通(passthrough)方面（即IO虚拟化）。</p>

<p>VT-x中在non-root模式下，MMU直接使用EPT page table来完成GPA-&gt;HVA-&gt;HPA的两级翻译， VT-d中在non-root模式下，则由IOMMU来使用Context Table和IOMMU page table完成设备DMA请求过程中的HPA-&gt;HVA-&gt;GPA的翻译． 二者极为相似，唯一的不同之处在于CPU访问内存（直通设备IO Memory）是通过MMU查找EPT页表完成地址翻译， 而直通设备访问内存的请求则是通过IOMMU查找IOMMU页表来完成地址翻译的。本文重点来探索一下Intel IOMMU的工作机制。</p>

<p>非根模式是Guest CPU的执行环境，根模式是Host CPU的执行环境</p>

<blockquote>
  <p>IOMMU - vt-d intel virtualization Technology for Directed I/O</p>
  <div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="n">ARMv8</span> <span class="n">Virtualization</span> <span class="n">Overview</span> <span class="n">https</span><span class="o">:</span><span class="c1">//kernelgo.org/armv8-virt-guide.html</span>
<span class="n">https</span><span class="o">:</span><span class="c1">//blog.csdn.net/21cnbao/article/details/105480147</span>
</pre></td></tr></tbody></table></code></div>  </div>
</blockquote>

<p><a href="/posts/.\images\linux-iommu\SMMU的位置.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\SMMU的位置.png" alt="image-20221121105727102" class="lazyload" data-proofer-ignore></a></p>

<p><strong>以Intel的IOMMU来分析：</strong></p>

<p><a href="/posts/.\images\linux-iommu\intel iommu硬件图.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\intel iommu硬件图.png" alt="image-20221114153201088" class="lazyload" data-proofer-ignore></a></p>

<h3 id="一虚拟地址"><span class="me-2">一、虚拟地址</span><a href="#一虚拟地址" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

<h4 id="1虚拟地址空间iova-domain"><span class="me-2">1、虚拟地址空间：iova domain</span><a href="#1虚拟地址空间iova-domain" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<p>iommu probe时，初始化iova domain</p>

<h5 id="1初始化保留区域"><span class="me-2">1&gt;初始化保留区域</span><a href="#1初始化保留区域" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p>dmar_init_reserved_ranges 初始化reserved_iova_list 初始化保留的区域。</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="n">detect_intel_iommu</span>
    <span class="o">|-&gt;</span> <span class="n">pci_iommu_init</span>
    	<span class="o">|-&gt;</span><span class="n">intel_iommu_init</span><span class="o">:</span><span class="mi">5148</span>
    		<span class="o">|-&gt;</span><span class="n">dmar_init_reserved_ranges</span>
    			<span class="o">|-&gt;</span><span class="n">init_iova_domain</span> <span class="o">&amp;</span><span class="n">reserved_iova_list</span>
</pre></td></tr></tbody></table></code></div></div>

<ul>
  <li>reserved_iova_list reserve部分，DMA不可用的地址</li>
</ul>

<p>下面两种range是需要保留的：</p>

<pre><code class="language-C">1 IOAPIC 0xfee00000~0xfeefffff APIC的寄存器地址：0xfee00000
2 所有PCI设备的MMIO空间 IORESOURCE_MEM
</code></pre>

<h5 id="2-按iommu_group做iova-domain申请"><span class="me-2">2&gt; 按iommu_group做iova domain申请</span><a href="#2-按iommu_group做iova-domain申请" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p>domain_alloc</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
</pre></td><td class="rouge-code"><pre><span class="nl">intel_iommu_init:</span> <span class="mi">5187</span>
    <span class="o">|-&gt;</span><span class="n">probe_acpi_namespace_devices</span>
		<span class="o">|-&gt;</span><span class="n">iommu_probe_device</span>
    		<span class="o">|-&gt;</span><span class="n">iommu_alloc_default_domain</span>
    			<span class="o">|-&gt;</span><span class="n">__iommu_domain_alloc</span>
    				<span class="o">|-&gt;</span> <span class="n">intel_iommu_domain_alloc</span> <span class="o">/</span> <span class="n">domain_alloc</span>
    					<span class="o">|-&gt;</span><span class="n">intel_init_iova_domain</span> <span class="k">if</span> <span class="n">IOMMU_DOMAIN_DMA</span>
</pre></td></tr></tbody></table></code></div></div>

<h4 id="2虚拟地址分配"><span class="me-2">2、虚拟地址分配：</span><a href="#2虚拟地址分配" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<h5 id="1-alloc_iova"><span class="me-2">1&gt; alloc_iova</span><a href="#1-alloc_iova" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre><span class="c1">//dma_alloc dma_map</span>
<span class="n">intel_dma_ops</span><span class="p">.</span><span class="n">map_page</span>
    <span class="o">|-&gt;</span><span class="n">intel_alloc_iova</span> <span class="c1">//if dev-&gt;dmamask &gt; 32, 先32bit以下,申请不到使用dev-&gt;dmamask </span>
    	<span class="o">|-&gt;</span><span class="n">alloc_iova_fast</span>
        	<span class="o">|-&gt;</span><span class="n">__iova_rcache_get</span> <span class="c1">//从rcache申请，fast路径</span>
    		 <span class="o">-&gt;</span><span class="n">alloc_iova</span> <span class="k">if</span> <span class="n">rcache</span> <span class="n">not</span> <span class="n">get</span> <span class="c1">//从iova_domian-&gt;rbroot中获取空闲</span>
</pre></td></tr></tbody></table></code></div></div>

<p>在rbtree中查找合适的位置，赋值给IOVA，并将其插入到rbtree中。</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="rouge-code"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">__alloc_and_insert_iova_range</span><span class="p">(</span><span class="k">struct</span> <span class="n">iova_domain</span> <span class="o">*</span><span class="n">iovad</span><span class="p">,</span>
		<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">size</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">limit_pfn</span><span class="p">,</span>
			<span class="k">struct</span> <span class="n">iova</span> <span class="o">*</span><span class="n">new</span><span class="p">,</span> <span class="n">bool</span> <span class="n">size_aligned</span><span class="p">)</span>
<span class="p">{</span>
	<span class="p">...</span>
	<span class="cm">/* Walk the tree backwards */</span>
	<span class="n">spin_lock_irqsave</span><span class="p">(</span><span class="o">&amp;</span><span class="n">iovad</span><span class="o">-&gt;</span><span class="n">iova_rbtree_lock</span><span class="p">,</span> <span class="n">flags</span><span class="p">);</span>
	<span class="p">...</span>
	<span class="n">curr</span> <span class="o">=</span> <span class="n">__get_cached_rbnode</span><span class="p">(</span><span class="n">iovad</span><span class="p">,</span> <span class="n">limit_pfn</span><span class="p">);</span>
	<span class="n">curr_iova</span> <span class="o">=</span> <span class="n">rb_entry</span><span class="p">(</span><span class="n">curr</span><span class="p">,</span> <span class="k">struct</span> <span class="n">iova</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>
	<span class="k">do</span> <span class="p">{</span>
		<span class="n">limit_pfn</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">limit_pfn</span><span class="p">,</span> <span class="n">curr_iova</span><span class="o">-&gt;</span><span class="n">pfn_lo</span><span class="p">);</span>
		<span class="n">new_pfn</span> <span class="o">=</span> <span class="p">(</span><span class="n">limit_pfn</span> <span class="o">-</span> <span class="n">size</span><span class="p">)</span> <span class="o">&amp;</span> <span class="n">align_mask</span><span class="p">;</span>
		<span class="n">prev</span> <span class="o">=</span> <span class="n">curr</span><span class="p">;</span>
		<span class="n">curr</span> <span class="o">=</span> <span class="n">rb_prev</span><span class="p">(</span><span class="n">curr</span><span class="p">);</span>
		<span class="n">curr_iova</span> <span class="o">=</span> <span class="n">rb_entry</span><span class="p">(</span><span class="n">curr</span><span class="p">,</span> <span class="k">struct</span> <span class="n">iova</span><span class="p">,</span> <span class="n">node</span><span class="p">);</span>
	<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">curr</span> <span class="o">&amp;&amp;</span> <span class="n">new_pfn</span> <span class="o">&lt;=</span> <span class="n">curr_iova</span><span class="o">-&gt;</span><span class="n">pfn_hi</span><span class="p">);</span>
	<span class="p">...</span>
	<span class="cm">/* pfn_lo will point to size aligned address if size_aligned is set */</span>
	<span class="n">new</span><span class="o">-&gt;</span><span class="n">pfn_lo</span> <span class="o">=</span> <span class="n">new_pfn</span><span class="p">;</span>
	<span class="n">new</span><span class="o">-&gt;</span><span class="n">pfn_hi</span> <span class="o">=</span> <span class="n">new</span><span class="o">-&gt;</span><span class="n">pfn_lo</span> <span class="o">+</span> <span class="n">size</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>

	<span class="cm">/* If we have 'prev', it's a valid place to start the insertion. */</span>
	<span class="n">iova_insert_rbtree</span><span class="p">(</span><span class="o">&amp;</span><span class="n">iovad</span><span class="o">-&gt;</span><span class="n">rbroot</span><span class="p">,</span> <span class="n">new</span><span class="p">,</span> <span class="n">prev</span><span class="p">);</span>
	<span class="n">__cached_rbnode_insert_update</span><span class="p">(</span><span class="n">iovad</span><span class="p">,</span> <span class="n">new</span><span class="p">);</span>
	<span class="p">...</span>
<span class="p">}</span>

</pre></td></tr></tbody></table></code></div></div>

<p>alloc_iova是最简单的分配机制，没有guard区域。申请的iova地址就是连续的。</p>

<p>验证：</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="rouge-code"><pre><span class="k">static</span> <span class="n">__init</span> <span class="kt">int</span> <span class="nf">test_module_init</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
        <span class="k">struct</span> <span class="n">iova_domain</span> <span class="o">*</span><span class="n">test_iovad</span><span class="p">;</span>
        <span class="k">struct</span> <span class="n">iova</span> <span class="o">*</span><span class="n">iova1</span><span class="p">,</span> <span class="o">*</span><span class="n">iova2</span><span class="p">;</span>

        <span class="n">test_iovad</span> <span class="o">=</span> <span class="n">kmalloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span> <span class="n">iova_domain</span><span class="p">),</span> <span class="n">GFP_KERNEL</span><span class="p">);</span>
        <span class="n">init_iova_domain</span><span class="p">(</span><span class="n">test_iovad</span><span class="p">,</span> <span class="mi">1UL</span> <span class="o">&lt;&lt;</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>

        <span class="n">iova1</span> <span class="o">=</span> <span class="n">alloc_iova</span><span class="p">(</span><span class="n">test_iovad</span><span class="p">,</span> <span class="mi">1UL</span> <span class="o">&lt;&lt;</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">1UL</span> <span class="o">&lt;&lt;</span> <span class="mi">32</span><span class="p">,</span> <span class="mi">1UL</span> <span class="o">&lt;&lt;</span> <span class="mi">12</span><span class="p">);</span>
        <span class="n">iova2</span> <span class="o">=</span> <span class="n">alloc_iova</span><span class="p">(</span><span class="n">test_iovad</span><span class="p">,</span> <span class="mi">1UL</span> <span class="o">&lt;&lt;</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">1UL</span> <span class="o">&lt;&lt;</span> <span class="mi">32</span><span class="p">,</span> <span class="mi">1UL</span> <span class="o">&lt;&lt;</span> <span class="mi">12</span><span class="p">);</span>

        <span class="n">printk</span><span class="p">(</span><span class="s">"iova1 %lx %lx</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">iova1</span><span class="o">-&gt;</span><span class="n">pfn_lo</span><span class="p">,</span> <span class="n">iova1</span><span class="o">-&gt;</span><span class="n">pfn_hi</span><span class="p">);</span>
        <span class="n">printk</span><span class="p">(</span><span class="s">"iova2 %lx %lx</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">iova2</span><span class="o">-&gt;</span><span class="n">pfn_lo</span><span class="p">,</span> <span class="n">iova2</span><span class="o">-&gt;</span><span class="n">pfn_hi</span><span class="p">);</span>

        <span class="n">__free_iova</span><span class="p">(</span><span class="n">test_iovad</span><span class="p">,</span> <span class="n">iova1</span><span class="p">);</span>
        <span class="n">__free_iova</span><span class="p">(</span><span class="n">test_iovad</span><span class="p">,</span> <span class="n">iova2</span><span class="p">);</span>
        <span class="n">kfree</span><span class="p">(</span><span class="n">test_iovad</span><span class="p">);</span>

        <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="p">[</span>  <span class="mi">110</span><span class="p">.</span><span class="mi">267837</span><span class="p">]</span> <span class="n">iova1</span> <span class="n">fffff000</span> <span class="n">ffffffff</span>
<span class="p">[</span>  <span class="mi">110</span><span class="p">.</span><span class="mi">267838</span><span class="p">]</span> <span class="n">iova2</span> <span class="n">ffffe000</span> <span class="n">ffffefff</span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="2-free_iova"><span class="me-2">2&gt; free_iova</span><a href="#2-free_iova" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="c1">//dma_unmap</span>
<span class="n">free_iova_fast</span>
    <span class="o">|-&gt;</span><span class="n">iova_rcache_insert</span> <span class="c1">//can insert rcache? if true, insert and return;</span>
     <span class="o">-&gt;</span> <span class="n">free_iova</span> <span class="k">if</span> <span class="n">can</span> <span class="n">not</span> <span class="n">insert</span> <span class="n">rcache</span> <span class="c1">//从iova_domian-&gt;rbroot 删除对应项</span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="3-split_and_remove_iova"><span class="me-2">3&gt; split_and_remove_iova</span><a href="#3-split_and_remove_iova" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p>有功能实现，但无调用关系，也未导出。</p>

<p>总结：</p>

<p>1、虚拟地址空间</p>

<ul>
  <li>
    <p>虚拟地址有不可用的空间，需要被预留</p>
  </li>
  <li>
    <p>2、按照iommu_group分别独立虚拟地址空间</p>
  </li>
</ul>

<p>2、虚拟地址分配</p>

<ul>
  <li>rcache层做快速分配128K以下</li>
  <li>rbtree记录已申请部分，进行分配</li>
</ul>

<p>一、疑问</p>

<p>1、硬件无关的内存管理部分但有与具体功能(或者特殊限制等等因素)导致不同硬件存在差异怎么处理？</p>

<p><a href="/posts/.\images\linux-iommu\iommu结构体.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\iommu结构体.png" class="lazyload" data-proofer-ignore></a></p>

<ul>
  <li>struct inte_iommu：iommu硬件在驱动层所对应的概念</li>
  <li>struct iommu_group: 一个group下面可以对应多个或者一个硬件设备,使用相同的streamid</li>
  <li>struct dmar_domain: dmar_domain里面存储的是iova-&gt;hpa的转换页表，一个dmar_domain可以为多个或者一个设备服务。</li>
  <li>struct iommu_domain: 一个iommu_domain里面可以有多个iommu_group，然后每个iommu_group通过iommu_domain最终找到dmar_domain进行转换。</li>
</ul>

<h3 id="二逻辑映射iova_to_phys"><span class="me-2">二、逻辑映射iova_to_phys</span><a href="#二逻辑映射iova_to_phys" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

<p>对于IOMMU的iova_to_phys是必要，驱动需要获取phys做访问。</p>

<p>linux的实现都是遍历页表获取对应phys。</p>

<h4 id="1smmu"><span class="me-2">1、SMMU</span><a href="#1smmu" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<p>arm_lpae_iova_to_phys</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="k">struct</span> <span class="n">iommu_ops</span> <span class="n">arm_smmu_ops</span><span class="p">.</span><span class="n">iova_to_phys</span>
	<span class="o">+-&gt;</span> <span class="n">arm_smmu_iova_to_phys</span>
    	<span class="o">+-&gt;</span><span class="k">struct</span> <span class="n">io_pgtable_ops</span><span class="p">.</span><span class="n">iova_to_phys</span>  <span class="c1">//arm_lpae_alloc_pgtable函数installed</span>
            <span class="o">+-&gt;</span><span class="n">arm_lpae_iova_to_phys</span> <span class="c1">//在内存上做多级页表遍历，获取最后的phys</span>
</pre></td></tr></tbody></table></code></div></div>

<h4 id="2intel-iommu"><span class="me-2">2、intel IOMMU:</span><a href="#2intel-iommu" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="k">struct</span> <span class="n">iommu_ops</span> <span class="n">intel_iommu_ops</span><span class="p">.</span><span class="n">iova_to_phys</span>
    <span class="o">+-&gt;</span><span class="n">intel_iommu_iova_to_phys</span>
    	<span class="o">+-&gt;</span><span class="n">pfn_to_dma_pte</span> <span class="c1">//走页表，如果没有映射，分配页添加映射</span>
</pre></td></tr></tbody></table></code></div></div>

<h3 id="三smmu与intel-iommu的页表管理"><span class="me-2">三、SMMU与Intel IOMMU的页表管理</span><a href="#三smmu与intel-iommu的页表管理" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

<h4 id="1smmu的页表"><span class="me-2">1、SMMU的页表：</span><a href="#1smmu的页表" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<p>reference: <a href="./word/iommu/SMMUv3_architecture_specification_IHI0070B.pdf">SMMUv3_architecture_specification_IHI0070B</a></p>

<p><a href="/posts/.\images\linux-iommu\smmu页表翻译.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\smmu页表翻译.png" div="" align="left" style="zoom:60%" class="lazyload" data-proofer-ignore></a></p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="mi">3</span><span class="p">.</span><span class="mi">13</span><span class="p">.</span><span class="mi">5</span> <span class="n">HTTU</span> <span class="n">with</span> <span class="n">two</span> <span class="n">stages</span> <span class="n">of</span> <span class="n">translation</span>
<span class="n">When</span> <span class="n">two</span> <span class="n">stages</span> <span class="n">of</span> <span class="n">translation</span> <span class="n">exist</span><span class="p">,</span> <span class="n">multiple</span> <span class="n">TTDs</span> <span class="n">determine</span> <span class="n">the</span> <span class="n">translation</span><span class="p">,</span> <span class="n">that</span> <span class="n">is</span> <span class="n">the</span> <span class="n">stage</span> <span class="mi">1</span> <span class="n">TTD</span><span class="p">,</span> <span class="n">the</span> <span class="n">stage</span> <span class="mi">2</span>
<span class="n">TTDs</span> <span class="n">mapping</span> <span class="n">all</span> <span class="n">steps</span> <span class="n">of</span> <span class="n">the</span> <span class="n">stage</span> <span class="mi">1</span> <span class="n">walk</span><span class="p">,</span> <span class="n">and</span> <span class="n">finally</span> <span class="n">the</span> <span class="n">stage</span> <span class="mi">2</span> <span class="n">TTD</span> <span class="n">mapping</span> <span class="n">the</span> <span class="n">IPA</span> <span class="n">output</span> <span class="n">of</span> <span class="n">stage</span> <span class="mi">1</span><span class="p">.</span>
<span class="n">Therefore</span> <span class="n">one</span> <span class="n">access</span> <span class="n">might</span> <span class="n">result</span> <span class="n">in</span> <span class="n">several</span> <span class="n">TTD</span> <span class="n">updates</span>
</pre></td></tr></tbody></table></code></div></div>

<p><a href="/posts/.\images\linux-iommu\smmy translation lookup sequence.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\smmy translation lookup sequence.png" div="" align="left" style="zoom:70%" class="lazyload" data-proofer-ignore></a></p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="n">Stage1</span><span class="err">和</span><span class="n">Stage2</span><span class="err">同时支持</span><span class="n">AArch32</span><span class="p">(</span><span class="n">LPAE</span><span class="o">:</span> <span class="n">Large</span> <span class="n">Page</span> <span class="n">Address</span> <span class="n">Extension</span><span class="p">)</span> 
</pre></td></tr></tbody></table></code></div></div>

<p>显而易见：</p>

<p>1&gt;SMMU/IOMMU的页表存在主存上</p>

<p>2&gt;SMMU的页表级数为4级</p>

<p>3&gt;支持page size:  IDR5_GRAN4K&lt;4K 2M 1G&gt;;  IDR5_GRAN16K&lt;16K 32M&gt;; IDR5_GRAN64K&lt;64k 512M&gt;</p>

<p>Smmu的页表walk函数：arm_lpae_iova_to_phys</p>

<p>IO pagetable TLB flush函数：io_pgtable_tlb_flush_all、io_pgtable_tlb_add_flush、io_pgtable_tlb_sync</p>

<h5 id="1map-页表"><span class="me-2">1、map 页表</span><a href="#1map-页表" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p>SMMU的嵌套翻译：stage1 + stage2.</p>

<p><a href="/posts/.\images\linux-iommu\SMMU翻译.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\SMMU翻译.png" div="" align="left" style="zoom:60%" class="lazyload" data-proofer-ignore></a></p>

<div class="language-plaintext highlighter-rouge"><div class="code-header">
        <span data-label-text="Plaintext"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>TT - Translation table, synonymous with Page Table, as used by ARM architecture
TTD - Translation table descriptor, synonymous with Page Table Entry, as used by the ARM architecture
LPAE - Large Physical Address Extension
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="c1">//iommu_dma_ops  arm_smmu_ops</span>
<span class="n">io_pgtable_init_table</span> 
    <span class="o">-&gt;</span><span class="n">io_pgtable_arm_64_lpae_s1_init_fns</span><span class="p">.</span><span class="n">alloc</span> <span class="c1">//arm_64_lpae_alloc_pgtable_s1 钩子1 硬件</span>
    	<span class="o">-&gt;</span><span class="n">__arm_lpae_alloc_pages</span>
<span class="c1">//cfg-&gt;arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data-&gt;pgd) </span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="c1">//iommu_domain-&gt;ops-&gt;map</span>
<span class="n">arm_lpae_alloc_pgtable</span>
	<span class="o">-&gt;</span><span class="n">data</span><span class="o">-&gt;</span><span class="n">iop</span><span class="p">.</span><span class="n">ops</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="n">dma_map_single</span>
    <span class="o">-&gt;</span> <span class="n">iommu_dma_ops</span><span class="p">.</span><span class="n">map_page</span><span class="c1">// __iommu_dma_map 钩子2 DMA框架</span>
    	<span class="o">-&gt;</span><span class="n">iommu_map</span>
    		<span class="o">-&gt;</span><span class="n">iommu_domain</span><span class="o">-&gt;</span><span class="n">ops</span><span class="o">-&gt;</span><span class="n">map</span> <span class="c1">//arm_smmu_map 钩子3 IMMU框架</span>
				<span class="o">-&gt;</span><span class="n">arm_lpae_map</span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="2tlb-flush函数"><span class="me-2">2、TLB flush函数</span><a href="#2tlb-flush函数" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p>arm64 SMMU: arm_smmu_flush_ops</p>

<p>通过cmdQ发送TLBI命令，是对应的TLB无效化。</p>

<p>可参考SMMU spec 4.4章节</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="rouge-code"><pre><span class="c1">//io_pgtable_tlb_add_flush</span>
<span class="k">static</span> <span class="kt">void</span> <span class="nf">arm_smmu_tlb_inv_range_nosync</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">iova</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">size</span><span class="p">,</span>
					  <span class="kt">size_t</span> <span class="n">granule</span><span class="p">,</span> <span class="n">bool</span> <span class="n">leaf</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">cookie</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">smmu_domain</span><span class="o">-&gt;</span><span class="n">stage</span> <span class="o">==</span> <span class="n">ARM_SMMU_DOMAIN_S1</span><span class="p">)</span> <span class="p">{</span>
		<span class="n">cmd</span><span class="p">.</span><span class="n">opcode</span>	<span class="o">=</span> <span class="n">smmu</span><span class="o">-&gt;</span><span class="n">features</span> <span class="o">&amp;</span> <span class="n">ARM_SMMU_FEAT_E2H</span> <span class="o">?</span>
				  <span class="n">CMDQ_OP_TLBI_EL2_VA</span> <span class="o">:</span> <span class="n">CMDQ_OP_TLBI_NH_VA</span><span class="p">;</span>  
		<span class="n">cmd</span><span class="p">.</span><span class="n">tlbi</span><span class="p">.</span><span class="n">asid</span>	<span class="o">=</span> <span class="n">smmu_domain</span><span class="o">-&gt;</span><span class="n">s1_cfg</span><span class="p">.</span><span class="n">cd0</span><span class="o">-&gt;</span><span class="n">tag</span><span class="p">;</span>
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="n">cmd</span><span class="p">.</span><span class="n">opcode</span>	<span class="o">=</span> <span class="n">CMDQ_OP_TLBI_S2_IPA</span><span class="p">;</span>
		<span class="n">cmd</span><span class="p">.</span><span class="n">tlbi</span><span class="p">.</span><span class="n">vmid</span>	<span class="o">=</span> <span class="n">smmu_domain</span><span class="o">-&gt;</span><span class="n">s2_cfg</span><span class="p">.</span><span class="n">vmid</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="k">do</span> <span class="p">{</span>
		<span class="n">arm_smmu_cmdq_issue_cmd</span><span class="p">(</span><span class="n">smmu</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">cmd</span><span class="p">);</span> <span class="c1">//cmd S1: TLBI命令</span>
		<span class="n">cmd</span><span class="p">.</span><span class="n">tlbi</span><span class="p">.</span><span class="n">addr</span> <span class="o">+=</span> <span class="n">granule</span><span class="p">;</span>
	<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">size</span> <span class="o">-=</span> <span class="n">granule</span><span class="p">);</span>
<span class="p">}</span>

</pre></td></tr></tbody></table></code></div></div>

<h4 id="2intel-iommu-1"><span class="me-2">2、intel IOMMU:</span><a href="#2intel-iommu-1" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<p><a href="./word/iommu/vt-directed-io-spec.pdf">vt-directed-io-spec.pdf</a></p>

<p><a href="/posts/.\images\linux-iommu\intel-iommu页表格式.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\intel-iommu页表格式.png" class="lazyload" data-proofer-ignore></a>
<a href="/posts/.\images\linux-iommu\intel-iommu scalable页表.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\intel-iommu scalable页表.png" class="lazyload" data-proofer-ignore></a></p>

<p>参考vt-directed-io-spec.pdf的第3.5章节： Hierarchical Translation Structures</p>

<p>IOMMU:</p>

<p>1&gt; 支持4K 2M 1G的page size。</p>

<h5 id="1map页表"><span class="me-2">1、map页表</span><a href="#1map页表" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p>仅贴上4K，其他查看对应章节。4K table&lt;9 9 9 9 12&gt;</p>

<p><a href="/posts/.\images\linux-iommu\iommu-4k页表.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\iommu-4k页表.png" div="" align="left" style="zoom:70%" class="lazyload" data-proofer-ignore></a></p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="n">intel_iommu_ops</span><span class="p">.</span><span class="n">map</span>
    <span class="o">-&gt;</span><span class="n">intel_iommu_map</span>
    	<span class="o">-&gt;</span><span class="n">domain_mapping</span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="2flush-tlb"><span class="me-2">2、flush tlb</span><a href="#2flush-tlb" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<ul>
  <li>
    <p>ASID-based IOTLB Invalidate Descriptor &lt;DID +  PASID + [start ] + [end]&gt;</p>
  </li>
  <li>
    <p>Device-TLB Invalidate Descriptor &lt;Source-ID (SID) + [PASOID] + [start] + [end]&gt;</p>

    <pre><code class="language-C">Source-ID (SID): The SID field indicates the source-id of the endpoint device whose Device-TLB
needs to be invalidated.
</code></pre>
  </li>
  <li>
    <p>GLOBAL FLUSH &lt; DID&gt;</p>
  </li>
</ul>

<p>IOMMU刷新tlb：__iommu_flush_iotlb or dmar_enable_qi</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="rouge-code"><pre><span class="c1">//__iommu_flush_iotlb 	</span>
	<span class="k">case</span> <span class="n">DMA_TLB_GLOBAL_FLUSH</span><span class="p">:</span>
		<span class="cm">/* global flush doesn't need set IVA_REG */</span>
		<span class="n">val</span> <span class="o">=</span> <span class="n">DMA_TLB_GLOBAL_FLUSH</span><span class="o">|</span><span class="n">DMA_TLB_IVT</span><span class="p">;</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">DMA_TLB_DSI_FLUSH</span><span class="p">:</span>
		<span class="n">val</span> <span class="o">=</span> <span class="n">DMA_TLB_DSI_FLUSH</span><span class="o">|</span><span class="n">DMA_TLB_IVT</span><span class="o">|</span><span class="n">DMA_TLB_DID</span><span class="p">(</span><span class="n">did</span><span class="p">);</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">DMA_TLB_PSI_FLUSH</span><span class="p">:</span>
		<span class="n">val</span> <span class="o">=</span> <span class="n">DMA_TLB_PSI_FLUSH</span><span class="o">|</span><span class="n">DMA_TLB_IVT</span><span class="o">|</span><span class="n">DMA_TLB_DID</span><span class="p">(</span><span class="n">did</span><span class="p">);</span>
		<span class="cm">/* IH bit is passed in as part of address */</span>
		<span class="n">val_iva</span> <span class="o">=</span> <span class="n">size_order</span> <span class="o">|</span> <span class="n">addr</span><span class="p">;</span>
		<span class="k">break</span><span class="p">;</span>
</pre></td></tr></tbody></table></code></div></div>

<p>dmar_enable_qi支持按照地址和order来flush。</p>

<p>嵌套翻译：stage 1和stage 2同时使用的嵌套翻译。</p>

<p><a href="/posts/.\images\linux-iommu\iommu嵌套翻译.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\iommu嵌套翻译.png" div="" align="left" style="zoom:70%" class="lazyload" data-proofer-ignore></a></p>

<h4 id="3amd-iommu"><span class="me-2">3、amd iommu</span><a href="#3amd-iommu" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="mi">1</span> <span class="n">domain</span><span class="o">-&gt;</span><span class="n">id</span><span class="err">是怎么用的，为什么能在</span><span class="n">iotlb</span> <span class="n">flush</span><span class="err">的时候用上。然后搞清楚</span><span class="n">kpi</span><span class="err">中要不要给</span><span class="n">pmap_create</span><span class="err">增加参数</span>
<span class="mi">2</span> <span class="n">pmap_create</span><span class="err">在创建</span><span class="n">pmap</span><span class="err">时，应该增加一个自定义的参数，还是以</span><span class="n">gm_dev_create</span><span class="err">时增加的</span><span class="n">dev</span><span class="err">性质作为参考，不需要增加自定义的参数，即：以</span><span class="n">gm_dev_cap_t</span><span class="err">传入，还是架构上需要</span><span class="n">pmap_create</span><span class="err">时传入动态的自定义参数</span>
<span class="mi">3</span> <span class="err">增加一个遗留问题，</span><span class="n">iommu</span><span class="err">的</span><span class="n">iotlb</span> <span class="n">coalesced</span> <span class="n">invl</span><span class="err">的技术需要探索分</span><span class="n">iommu</span> <span class="n">address</span> <span class="n">space</span><span class="err">来</span><span class="n">invl</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="n">protection_domain_init</span>
<span class="n">PDE</span><span class="err">：</span> <span class="n">page</span> <span class="n">directory</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
</pre></td><td class="rouge-code"><pre><span class="n">iommu_bus_notifier</span>
    <span class="o">-&gt;</span><span class="n">iommu_probe_device</span>

<span class="n">bus_set_iommu</span>
    <span class="o">-&gt;</span><span class="n">iommu_bus_init</span>
		<span class="o">-&gt;</span><span class="n">bus_iommu_probe</span>
    		<span class="o">-&gt;</span><span class="n">probe_iommu_group</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre><span class="c1">//IOMMU_ENABLED -&gt;amd_iommu_init_pci</span>
<span class="mi">1</span> <span class="o">-&gt;</span> <span class="n">iommu_group_alloc_default_domain</span>
    <span class="o">-&gt;</span><span class="n">__iommu_domain_alloc</span>
<span class="mi">2</span> <span class="o">-&gt;</span> <span class="n">__iommu_attach_device</span>
     <span class="o">-&gt;</span> <span class="n">set_dte_entry</span>
    	<span class="o">-&gt;</span><span class="n">amd_iommu_dev_table</span><span class="o">&lt;</span><span class="err">变量</span><span class="o">&gt;</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="c1">//IOMMU_ACPI_FINISHED</span>
    <span class="o">-&gt;</span> <span class="n">iommu_set_device_table</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="rouge-code"><pre><span class="n">IOMMU_ACPI_FINISHED</span>
	<span class="o">-&gt;</span><span class="n">IOMMU_ENABLED</span>

	<span class="k">case</span> <span class="n">IOMMU_ACPI_FINISHED</span><span class="p">:</span>
		<span class="n">early_enable_iommus</span><span class="p">();</span>
		<span class="n">x86_platform</span><span class="p">.</span><span class="n">iommu_shutdown</span> <span class="o">=</span> <span class="n">disable_iommus</span><span class="p">;</span>
		<span class="n">init_state</span> <span class="o">=</span> <span class="n">IOMMU_ENABLED</span><span class="p">;</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">IOMMU_ENABLED</span><span class="p">:</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="err">需要入参</span><span class="k">struct</span> <span class="n">device</span> <span class="o">+</span> <span class="n">iommu_domain</span><span class="o">?</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="n">dev_iommu_priv_set</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-plaintext highlighter-rouge"><div class="code-header">
        <span data-label-text="Plaintext"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre>probe_device
	-&gt;| iommu_init_device
		-&gt;| devid = get_device_id() 总线 + 设备功能号
</pre></td></tr></tbody></table></code></div></div>

<h3 id="四-ats"><span class="me-2">四、 ATS</span><a href="#四-ats" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

<p><a href="https://aijishu.com/a/1060000000209080">ARM系列 – SMMU（二）</a></p>

<p><a href="https://cloud.tencent.com/developer/article/1905267">PCIe地址转换服务（ATS）详解</a></p>

<p><a href="https://zhuanlan.zhihu.com/p/411746688">PCIe的ATS机制</a></p>

<h4 id="1ats机制想要解决的问题"><span class="me-2">1、ATS机制想要解决的问题</span><a href="#1ats机制想要解决的问题" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<div class="table-wrapper"><table>
  <tbody>
    <tr>
      <td>​</td>
      <td>对于IO设备往CPU的数据流，其IOMMU/SMMU/VT-d的查表性能在整个IO性能中显得极为关键，查表性能的好坏至今影响IO性能的好坏；</td>
    </tr>
  </tbody>
</table></div>

<div class="table-wrapper"><table>
  <tbody>
    <tr>
      <td>​</td>
      <td>能够分担主机（CPU）侧的查表压力，特别是大带宽、大拓扑下的IO数据流，CPU侧的IOMMU/SMMU/VT-d的查表将会成为性能瓶颈，而ATS机制正好可以提供将这些查表压力卸载到不同的设备中。</td>
    </tr>
  </tbody>
</table></div>

<h4 id="2地址翻译过程"><span class="me-2">2、地址翻译过程</span><a href="#2地址翻译过程" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<p><a href="/posts/.\images\linux-iommu\ATS翻译过程.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\ATS翻译过程.png" alt="image-20221219202236856" class="lazyload" data-proofer-ignore></a></p>

<div class="language-xml highlighter-rouge"><div class="code-header">
        <span data-label-text="XML"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
</pre></td><td class="rouge-code"><pre>1 PCIE Device首先通过本地ATC查找某页地址的转换，未成功则通过ATS发起针对页地址的translation request
2 SMMU收到RC的地址转换请求，查找本地TLB，如果没有，硬件进行page table walk,若页表不存在或者页不在内存中，则需要返回translationfault给PCIE device.
3 PCIE PRI 发起page request给RC，携带streamID,substreamID,地址等信息
4 SMMU获得该信息后组成数据格式包放入PRI queue ，并产生中断通知CPU（OS）
5 OS 内存管理子系统将缺页补上，即处理IO Page fault handling
6 SMMU(RC)通过response告知device,发送page response,页处理完成，该内存页已经准备好，可进行DMA操作
7 PCIE Device发起DMA操作
</pre></td></tr></tbody></table></code></div></div>

<h3 id="五昇腾smmu和mmu共页表"><span class="me-2">五、昇腾SMMU和MMU共页表？</span><a href="#五昇腾smmu和mmu共页表" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

<p>PASID is an optional feature that enables sharing of a single Endpoint device across multiple processes while providing each process a complete 64-bit virtual address space. In practice, this feature adds support for a TLP prefix that contains a 20-bit address space that can be added to memory transaction TLPs.</p>

<h4 id="一由amd的sva方案开始"><span class="me-2">一、由AMD的SVA方案开始</span><a href="#一由amd的sva方案开始" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<p>reference:</p>

<p><a href="./word/iommu/IOMMU_TUTORIAL_ASPLOS_2016.pdf">IOMMU_TUTORIAL_ASPLOS_2016.pdf</a></p>

<p><a href="./word/iommu/48882_IOMMU_3.05_PUB.pdf">48882_IOMMU_3.05_PUB.pdf</a></p>

<p><a href="/posts/.\images\linux-iommu\AMD64和IOMMU Share Page Tabel.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\AMD64和IOMMU Share Page Tabel.png" class="lazyload" data-proofer-ignore></a>
<a href="/posts/.\images\linux-iommu\AMD共页表方案1.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\AMD共页表方案1.png" class="lazyload" data-proofer-ignore></a></p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="n">Sharing</span> <span class="n">AMD64</span> <span class="n">Processor</span> <span class="n">and</span> <span class="n">IOMMU</span> <span class="n">Page</span> <span class="n">Tables</span><span class="err">—</span><span class="n">GPA</span><span class="o">-</span><span class="n">to</span><span class="o">-</span><span class="n">SPA</span>

<span class="n">If</span> <span class="n">software</span> <span class="n">requires</span> <span class="mi">64</span><span class="o">-</span><span class="n">bit</span> <span class="n">processor</span> <span class="k">virtual</span> <span class="n">addresses</span> <span class="n">to</span> <span class="n">be</span> <span class="n">identical</span> <span class="n">to</span> <span class="n">I</span><span class="o">/</span><span class="n">O</span> <span class="k">virtual</span> <span class="n">addresses</span><span class="p">,</span> <span class="n">including</span> <span class="n">negative</span> <span class="n">addresses</span><span class="p">,</span> <span class="n">software</span> <span class="n">needs</span> <span class="n">to</span> <span class="n">configure</span> <span class="n">the</span> <span class="n">IOMMU</span> <span class="n">with</span> <span class="n">the</span> <span class="mi">6</span><span class="o">-</span><span class="n">level</span> <span class="n">paging</span> <span class="n">structure</span> <span class="n">illustrated</span> <span class="n">in</span> <span class="n">Figure</span> <span class="mi">13</span><span class="p">,</span> <span class="n">where</span> <span class="mi">4</span> <span class="n">extra</span> <span class="mi">4</span><span class="o">-</span><span class="n">Kbyte</span> <span class="n">page</span> <span class="n">tables</span> <span class="p">(</span><span class="n">shaded</span><span class="p">)</span> <span class="n">at</span> <span class="n">levels</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="n">and</span> <span class="mi">4</span> <span class="n">are</span> <span class="n">used</span> <span class="n">solely</span> <span class="n">by</span> <span class="n">the</span> <span class="n">IOMMU</span><span class="p">,</span> <span class="n">and</span> <span class="n">sharing</span> <span class="n">with</span> <span class="n">processor</span> <span class="n">page</span> <span class="n">tables</span> <span class="n">occurs</span> <span class="n">only</span> <span class="n">at</span> <span class="n">levels</span> <span class="mi">3</span> <span class="n">and</span> <span class="n">below</span><span class="p">.</span>
</pre></td></tr></tbody></table></code></div></div>

<p><a href="/posts/.\images\linux-iommu\HSA ShareMem.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\HSA ShareMem.png" class="lazyload" data-proofer-ignore></a></p>

<h4 id="二推到社区的sva"><span class="me-2">二、推到社区的SVA</span><a href="#二推到社区的sva" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<p>reference：<a href="https://lwn.net/Articles/747230/">Shared Virtual Addressing for the IOMMU</a></p>

<p>SVA mostly aims at simplifying DMA management.</p>

<p>补丁列表：2017/11/17</p>

<p>https://www.spinics.net/lists/kernel/msg2651481.html</p>

<p>https://www.spinics.net/lists/arm-kernel/msg609771.html</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="rouge-code"><pre><span class="n">Sharing</span> <span class="n">process</span> <span class="n">address</span> <span class="n">spaces</span> <span class="n">with</span> <span class="n">devices</span> <span class="n">allows</span> <span class="n">to</span> <span class="n">rely</span> <span class="n">on</span> <span class="n">core</span> <span class="n">kernel</span>
<span class="n">memory</span> <span class="n">management</span> <span class="k">for</span> <span class="n">DMA</span><span class="p">,</span> <span class="n">removing</span> <span class="n">some</span> <span class="n">complexity</span> <span class="n">from</span> <span class="n">application</span> <span class="n">and</span>
<span class="n">device</span> <span class="n">drivers</span><span class="p">.</span> <span class="n">After</span> <span class="n">binding</span> <span class="n">to</span> <span class="n">a</span> <span class="n">device</span><span class="p">,</span> <span class="n">applications</span> <span class="n">can</span> <span class="n">instruct</span> <span class="n">it</span> <span class="n">to</span>
<span class="n">perform</span> <span class="n">DMA</span> <span class="n">on</span> <span class="n">buffers</span> <span class="n">obtained</span> <span class="n">with</span> <span class="n">malloc</span><span class="p">.</span>
    
<span class="n">The</span> <span class="n">device</span><span class="p">,</span> <span class="n">buses</span> <span class="n">and</span> <span class="n">the</span> <span class="n">IOMMU</span> <span class="n">must</span> <span class="n">support</span> <span class="n">the</span> <span class="n">following</span> <span class="n">features</span><span class="o">:</span>
<span class="o">*</span> <span class="n">Multiple</span> <span class="n">address</span> <span class="n">spaces</span> <span class="n">per</span> <span class="n">device</span><span class="p">,</span> <span class="k">for</span> <span class="n">example</span> <span class="n">using</span> <span class="n">the</span> <span class="n">PCI</span> <span class="n">PASID</span>
  <span class="p">(</span><span class="n">Process</span> <span class="n">Address</span> <span class="n">Space</span> <span class="n">ID</span><span class="p">)</span> <span class="n">extension</span><span class="p">.</span> <span class="n">The</span> <span class="n">IOMMU</span> <span class="n">driver</span> <span class="n">allocates</span> <span class="n">a</span>
  <span class="n">PASID</span> <span class="n">and</span> <span class="n">the</span> <span class="n">device</span> <span class="n">uses</span> <span class="n">it</span> <span class="n">in</span> <span class="n">DMA</span> <span class="n">transactions</span><span class="p">.</span>
    
<span class="o">*</span> <span class="n">I</span><span class="o">/</span><span class="n">O</span> <span class="n">Page</span> <span class="n">Faults</span> <span class="p">(</span><span class="n">IOPF</span><span class="p">),</span> <span class="k">for</span> <span class="n">example</span> <span class="n">PCI</span> <span class="n">PRI</span> <span class="p">(</span><span class="n">Page</span> <span class="n">Request</span> <span class="n">Interface</span><span class="p">)</span> <span class="n">or</span>
  <span class="n">Arm</span> <span class="n">SMMU</span> <span class="n">stall</span><span class="p">.</span> <span class="n">The</span> <span class="n">core</span> <span class="n">mm</span> <span class="n">handles</span> <span class="n">translation</span> <span class="n">faults</span> <span class="n">from</span> <span class="n">the</span> <span class="n">IOMMU</span><span class="p">.</span>

<span class="o">*</span> <span class="n">MMU</span> <span class="n">and</span> <span class="n">IOMMU</span> <span class="n">implement</span> <span class="n">compatible</span> <span class="n">page</span> <span class="n">table</span> <span class="n">formats</span><span class="p">.</span>

<span class="n">This</span> <span class="n">series</span> <span class="n">requires</span> <span class="n">to</span> <span class="n">support</span> <span class="n">all</span> <span class="n">three</span> <span class="n">features</span><span class="p">.</span> <span class="n">I</span> <span class="n">tried</span> <span class="n">to</span>
<span class="n">facilitate</span> <span class="n">using</span> <span class="n">only</span> <span class="n">a</span> <span class="n">subset</span> <span class="n">of</span> <span class="n">them</span> <span class="n">but</span> <span class="n">enabling</span> <span class="n">it</span> <span class="n">requires</span> <span class="n">more</span>
<span class="n">work</span><span class="p">.</span> <span class="n">Upcoming</span> <span class="n">patches</span> <span class="n">will</span> <span class="n">enable</span> <span class="n">private</span> <span class="n">PASID</span> <span class="n">management</span><span class="p">,</span> <span class="n">which</span>
<span class="n">allows</span> <span class="n">device</span> <span class="n">driver</span> <span class="n">to</span> <span class="n">use</span> <span class="n">an</span> <span class="n">API</span> <span class="n">similar</span> <span class="n">to</span> <span class="n">classical</span> <span class="n">DMA</span><span class="p">,</span>
<span class="n">map</span><span class="p">()</span><span class="o">/</span><span class="n">unmap</span><span class="p">()</span> <span class="n">on</span> <span class="n">PASIDs</span><span class="p">.</span> <span class="n">In</span> <span class="n">the</span> <span class="n">future</span> <span class="n">device</span> <span class="n">drivers</span> <span class="n">should</span> <span class="n">also</span> <span class="n">be</span>
<span class="n">able</span> <span class="n">to</span> <span class="n">use</span> <span class="n">SVA</span> <span class="n">without</span> <span class="n">IOPF</span> <span class="n">by</span> <span class="n">pinning</span> <span class="n">all</span> <span class="n">pages</span><span class="p">,</span> <span class="n">or</span> <span class="n">without</span> <span class="n">PASID</span> <span class="n">by</span>
<span class="n">sharing</span> <span class="n">the</span> <span class="n">single</span> <span class="n">device</span> <span class="n">address</span> <span class="n">space</span> <span class="n">with</span> <span class="n">a</span> <span class="n">process</span><span class="p">.</span>

<span class="n">Although</span> <span class="n">we</span> <span class="n">don</span><span class="err">'</span><span class="n">t</span> <span class="n">have</span> <span class="n">any</span> <span class="n">performance</span> <span class="n">measurement</span> <span class="n">at</span> <span class="n">the</span> <span class="n">moment</span><span class="p">,</span> <span class="n">SVA</span>
<span class="n">will</span> <span class="n">likely</span> <span class="n">be</span> <span class="n">slower</span> <span class="n">than</span> <span class="n">classical</span> <span class="n">DMA</span> <span class="n">since</span> <span class="n">it</span> <span class="n">relies</span> <span class="n">on</span> <span class="n">page</span> <span class="n">faults</span><span class="p">,</span>
<span class="n">whereas</span> <span class="n">classical</span> <span class="n">DMA</span> <span class="n">pins</span> <span class="n">all</span> <span class="n">pages</span> <span class="n">in</span> <span class="n">memory</span><span class="p">.</span> <span class="n">SVA</span> <span class="n">mostly</span> <span class="n">aims</span> <span class="n">at</span>
<span class="n">simplifying</span> <span class="n">DMA</span> <span class="n">management</span><span class="p">,</span> <span class="n">but</span> <span class="n">also</span> <span class="n">improves</span> <span class="n">security</span> <span class="n">by</span> <span class="n">isolating</span>
<span class="n">address</span> <span class="n">spaces</span> <span class="n">in</span> <span class="n">devices</span><span class="p">.</span>

<span class="n">Intel</span> <span class="n">and</span> <span class="n">AMD</span> <span class="n">IOMMU</span> <span class="n">drivers</span> <span class="n">already</span> <span class="n">offer</span> <span class="n">slightly</span> <span class="n">differing</span> <span class="n">public</span>
<span class="n">functions</span> <span class="n">that</span> <span class="n">bind</span> <span class="n">process</span> <span class="n">address</span> <span class="n">spaces</span> <span class="n">to</span> <span class="n">devices</span><span class="p">.</span> <span class="n">Because</span> <span class="n">they</span> <span class="n">don</span><span class="err">'</span><span class="n">t</span>
<span class="n">go</span> <span class="n">through</span> <span class="n">an</span> <span class="n">architecture</span><span class="o">-</span><span class="n">agnostic</span> <span class="n">API</span><span class="p">,</span> <span class="n">only</span> <span class="n">integrated</span> <span class="n">devices</span> <span class="n">could</span>
<span class="n">use</span> <span class="n">them</span> <span class="n">so</span> <span class="n">far</span><span class="p">.</span>
</pre></td></tr></tbody></table></code></div></div>

<p>referecence: <a href="https://www.twblogs.net/a/5d839297bd9eee541c349c80">Linux SVA特性分析(未完)</a></p>

<p>这个特性的补丁涉及到IOMMU, PCI, 内存管理(MM),SMMU, VFIO, 虚拟化，DT, ACPI等方面的修改，所以补丁比较分散</p>

<p><a href="/posts/.\images\linux-iommu\upstream SVA.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\upstream SVA.png" class="lazyload" data-proofer-ignore></a>
<a href="/posts/.\images\linux-iommu\SVA概括图.png" class="popup img-link "><img data-src="/posts/.\images\linux-iommu\SVA概括图.png" alt="image-20221117164634804" class="lazyload" data-proofer-ignore></a></p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="rouge-code"><pre><span class="n">sva</span><span class="p">.</span><span class="n">c</span>
     <span class="n">Hardware</span> <span class="n">tables</span> <span class="n">describing</span> <span class="n">this</span> <span class="n">configuration</span> <span class="n">in</span> <span class="n">the</span> <span class="n">IOMMU</span> <span class="n">would</span> <span class="n">typically</span>
 <span class="o">*</span> <span class="n">look</span> <span class="n">like</span> <span class="n">this</span><span class="o">:</span>
 <span class="o">*</span>
 <span class="o">*</span>                                <span class="n">PASID</span> <span class="n">tables</span>
 <span class="o">*</span>                                 <span class="n">of</span> <span class="n">domain</span> <span class="n">A</span>
 <span class="o">*</span>                              <span class="p">.</span><span class="o">-&gt;+--------+</span>
 <span class="o">*</span>                             <span class="o">/</span> <span class="mi">0</span> <span class="o">|</span>        <span class="o">|-------&gt;</span> <span class="n">io_pgtable</span>
 <span class="o">*</span>                            <span class="o">/</span>    <span class="o">+--------+</span>
 <span class="o">*</span>            <span class="n">Device</span> <span class="n">tables</span>  <span class="o">/</span>   <span class="mi">1</span> <span class="o">|</span>        <span class="o">|-------&gt;</span> <span class="n">pgd</span> <span class="n">X</span>
 <span class="o">*</span>              <span class="o">+--------+</span>  <span class="o">/</span>      <span class="o">+--------+</span>
 <span class="o">*</span>      <span class="mo">00</span><span class="o">:</span><span class="mo">00</span><span class="p">.</span><span class="mi">0</span> <span class="o">|</span>      <span class="n">A</span> <span class="o">|-</span><span class="err">'</span>     <span class="mi">2</span> <span class="o">|</span>        <span class="o">|--</span><span class="p">.</span>
 <span class="o">*</span>              <span class="o">+--------+</span>         <span class="o">+--------+</span>   \
 <span class="o">*</span>              <span class="o">:</span>        <span class="o">:</span>       <span class="mi">3</span> <span class="o">|</span>        <span class="o">|</span>    \
 <span class="o">*</span>              <span class="o">+--------+</span>         <span class="o">+--------+</span>     <span class="o">--&gt;</span> <span class="n">pgd</span> <span class="n">Y</span>
 <span class="o">*</span>      <span class="mo">00</span><span class="o">:</span><span class="mo">01</span><span class="p">.</span><span class="mi">0</span> <span class="o">|</span>      <span class="n">B</span> <span class="o">|--</span><span class="p">.</span>                    <span class="o">/</span>
 <span class="o">*</span>              <span class="o">+--------+</span>   <span class="err">\</span>                  <span class="o">|</span>
 <span class="o">*</span>      <span class="mo">00</span><span class="o">:</span><span class="mo">01</span><span class="p">.</span><span class="mi">1</span> <span class="o">|</span>      <span class="n">B</span> <span class="o">|----+</span>   <span class="n">PASID</span> <span class="n">tables</span>  <span class="o">|</span>
 <span class="o">*</span>              <span class="o">+--------+</span>     <span class="err">\</span>   <span class="n">of</span> <span class="n">domain</span> <span class="n">B</span>  <span class="o">|</span>
 <span class="o">*</span>                              <span class="err">'</span><span class="o">-&gt;+--------+</span>   <span class="o">|</span>
 <span class="o">*</span>                               <span class="mi">0</span> <span class="o">|</span>        <span class="o">|--</span> <span class="o">|</span> <span class="o">--&gt;</span> <span class="n">io_pgtable</span>
 <span class="o">*</span>                                 <span class="o">+--------+</span>   <span class="o">|</span>
 <span class="o">*</span>                               <span class="mi">1</span> <span class="o">|</span>        <span class="o">|</span>   <span class="o">|</span>
 <span class="o">*</span>                                 <span class="o">+--------+</span>   <span class="o">|</span>
 <span class="o">*</span>                               <span class="mi">2</span> <span class="o">|</span>        <span class="o">|---</span><span class="err">'</span>
 <span class="o">*</span>                                 <span class="o">+--------+</span>
 <span class="o">*</span>                               <span class="mi">3</span> <span class="o">|</span>        <span class="o">|</span>
 <span class="o">*</span>                                 <span class="o">+--------+</span>
 <span class="o">*</span>
 <span class="o">*</span> <span class="n">With</span> <span class="n">this</span> <span class="n">model</span><span class="p">,</span> <span class="n">a</span> <span class="n">single</span> <span class="n">call</span> <span class="n">binds</span> <span class="n">all</span> <span class="n">devices</span> <span class="n">in</span> <span class="n">a</span> <span class="n">given</span> <span class="n">domain</span> <span class="n">to</span> <span class="n">an</span>
 <span class="o">*</span> <span class="n">address</span> <span class="n">space</span><span class="p">.</span> <span class="n">Other</span> <span class="n">devices</span> <span class="n">in</span> <span class="n">the</span> <span class="n">domain</span> <span class="n">will</span> <span class="n">get</span> <span class="n">the</span> <span class="n">same</span> <span class="n">bond</span> <span class="n">implicitly</span><span class="p">.</span>
 <span class="o">*</span> <span class="n">However</span><span class="p">,</span> <span class="n">users</span> <span class="n">must</span> <span class="n">issue</span> <span class="n">one</span> <span class="n">bind</span><span class="p">()</span> <span class="k">for</span> <span class="n">each</span> <span class="n">device</span><span class="p">,</span> <span class="n">because</span> <span class="n">IOMMUs</span> <span class="n">may</span>
 <span class="o">*</span> <span class="n">implement</span> <span class="n">SVA</span> <span class="n">differently</span><span class="p">.</span> <span class="n">Furthermore</span><span class="p">,</span> <span class="n">mandating</span> <span class="n">one</span> <span class="n">bind</span><span class="p">()</span> <span class="n">per</span> <span class="n">device</span>
 <span class="o">*</span> <span class="n">allows</span> <span class="n">the</span> <span class="n">driver</span> <span class="n">to</span> <span class="n">perform</span> <span class="n">sanity</span><span class="o">-</span><span class="n">checks</span> <span class="n">on</span> <span class="n">device</span> <span class="n">capabilities</span><span class="p">.</span>
 <span class="o">*</span>
 <span class="o">*</span> <span class="n">On</span> <span class="n">Arm</span> <span class="n">and</span> <span class="n">AMD</span> <span class="n">IOMMUs</span><span class="p">,</span> <span class="n">entry</span> <span class="mi">0</span> <span class="n">of</span> <span class="n">the</span> <span class="n">PASID</span> <span class="n">table</span> <span class="n">can</span> <span class="n">be</span> <span class="n">used</span> <span class="n">to</span> <span class="n">hold</span>
 <span class="o">*</span> <span class="n">non</span><span class="o">-</span><span class="n">PASID</span> <span class="n">translations</span><span class="p">.</span> <span class="n">In</span> <span class="n">this</span> <span class="k">case</span> <span class="n">PASID</span> <span class="mi">0</span> <span class="n">is</span> <span class="n">reserved</span> <span class="n">and</span> <span class="n">entry</span> <span class="mi">0</span> <span class="n">points</span>
 <span class="o">*</span> <span class="n">to</span> <span class="n">the</span> <span class="n">io_pgtable</span> <span class="n">base</span><span class="p">.</span> <span class="n">On</span> <span class="n">Intel</span> <span class="n">IOMMU</span><span class="p">,</span> <span class="n">the</span> <span class="n">io_pgtable</span> <span class="n">base</span> <span class="n">would</span> <span class="n">be</span> <span class="n">held</span> <span class="n">in</span>
 <span class="o">*</span> <span class="n">the</span> <span class="n">device</span> <span class="n">table</span> <span class="n">and</span> <span class="n">PASID</span> <span class="mi">0</span> <span class="n">would</span> <span class="n">be</span> <span class="n">available</span> <span class="n">to</span> <span class="n">the</span> <span class="n">allocator</span><span class="p">.</span>
 <span class="err">*/</span>
</pre></td></tr></tbody></table></code></div></div>

<p>linux 4.19代码</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="rouge-code"><pre><span class="c1">//sva.c</span>
<span class="n">__iommu_sva_bind_devicestruct</span> <span class="n">device</span> <span class="o">*</span><span class="n">dev</span><span class="p">,</span> <span class="k">struct</span> <span class="n">mm_struct</span> <span class="o">*</span><span class="n">mm</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">pasid</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">flags</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">drvdata</span>
    <span class="o">+-&gt;</span><span class="n">io_mm_alloc</span>
    	<span class="o">+-&gt;</span><span class="n">iommu_ops</span><span class="p">.</span><span class="n">mm_alloc</span> <span class="c1">//arm_smmu_ops.mm_alloc = arm_smmu_mm_alloc</span>
    			<span class="o">+-&gt;</span><span class="n">iommu_pasid_table_ops</span><span class="p">.</span><span class="n">alloc_shared_entry</span> <span class="c1">//</span>
    				<span class="o">+-&gt;</span><span class="n">arm_smmu_alloc_shared_cd</span> <span class="c1">//cd-&gt;ttbr	= virt_to_phys(mm-&gt;pgd); cd保存页表入口			</span>
     <span class="o">-&gt;</span><span class="n">io_mm_attach</span>
    	<span class="o">+-&gt;</span><span class="n">arm_smmu_mm_attach</span>
    		<span class="o">+-&gt;</span><span class="n">ops</span><span class="o">-&gt;</span><span class="n">set_entry</span> <span class="c1">//arm_smmu_set_cd</span>
    			<span class="o">+-&gt;</span><span class="n">arm_smmu_write_ctx_desc</span> <span class="c1">//将mm-&gt;pgd刷到对应pasid ttrb中 </span>
    <span class="c1">//至此device n的SMMU页表与进程A的MMU页表已经share，共同使用了</span>
    <span class="c1">//后面都是通过pagefault调用handle_mm_fault来处理缺页流程。</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="rouge-code"><pre><span class="c1">//sva.c 注册IOMMU page fault evt处理函数</span>
<span class="n">iommu_sva_device_init</span> <span class="c1">//iommu_register_device_fault_handler dev iommu_queue_iopf 注册设备的io page fault处理函数</span>
    
<span class="c1">//io-pgfault.c</span>
<span class="c1">//处理evt</span>
<span class="n">iommu_queue_iopf</span>
    <span class="o">+</span><span class="mi">1</span><span class="o">-&gt;</span> <span class="n">list_add</span><span class="p">(</span><span class="n">fault</span><span class="p">,</span> <span class="n">group</span><span class="p">)</span><span class="c1">//等待将group的所有fault evt</span>
     <span class="mi">2</span><span class="o">-&gt;</span><span class="n">INIT_WORK</span><span class="p">(</span><span class="n">work</span><span class="p">,</span> <span class="n">iopf_handle_group</span><span class="p">)</span> <span class="c1">//初始化pgfault处理worker</span>

<span class="c1">//fault处理worker</span>
<span class="n">iopf_handle_group</span>
    <span class="o">-&gt;</span><span class="n">iopf_handle_single</span> <span class="k">for</span> <span class="n">group</span><span class="o">-&gt;</span><span class="n">faults</span> <span class="c1">//对group fault遍历处理</span>
 
<span class="c1">//iopf_handle_single</span>
<span class="o">&gt;</span> <span class="n">evt</span> <span class="n">pgfault</span> <span class="n">request</span><span class="o">:</span> <span class="n">pasid</span> <span class="n">addr</span> <span class="n">perm</span><span class="err">权限</span>
<span class="mi">1</span><span class="err">、</span><span class="n">mm</span> <span class="o">=</span> <span class="n">iommu_sva_find</span><span class="p">(</span><span class="n">pasid</span><span class="p">)</span><span class="err">：</span> <span class="n">evt</span> <span class="n">pgfault</span> <span class="n">request</span><span class="err">的</span><span class="n">pasid</span> <span class="o">-&gt;</span> <span class="n">mm</span>
<span class="mi">2</span><span class="err">、</span><span class="n">vma</span> <span class="o">=</span> <span class="n">find_extend_vma</span><span class="p">(</span><span class="n">mm</span><span class="p">,</span> <span class="n">addr</span><span class="p">)</span>
<span class="mi">3</span><span class="err">、</span><span class="n">handle_mm_fault</span><span class="p">(</span><span class="n">vma</span><span class="p">,</span> <span class="n">prm</span><span class="o">-&gt;</span><span class="n">addr</span><span class="p">,</span> <span class="n">fault_flags</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span> <span class="c1">//处理page fault</span>
</pre></td></tr></tbody></table></code></div></div>

<p>linux 5.10：</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="rouge-code"><pre><span class="c1">//设备绑定进程</span>
<span class="n">iommu_sva_bind_device</span><span class="p">(</span><span class="k">struct</span> <span class="n">device</span> <span class="o">*</span><span class="n">dev</span><span class="p">,</span> <span class="k">struct</span> <span class="n">mm_struct</span> <span class="o">*</span><span class="n">mm</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">drvdata</span><span class="p">)</span>
    <span class="o">+-&gt;</span><span class="n">iommu_group_do_bind_dev</span> <span class="k">for</span> <span class="n">group</span> <span class="n">dev</span> 
        <span class="o">+-&gt;</span><span class="n">intel_iommu_ops</span><span class="p">.</span><span class="n">sva_bind</span> <span class="c1">//intel_svm_bind</span>
        	<span class="o">+-&gt;</span><span class="n">intel_svm_bind_mm</span>
        		<span class="o">+</span><span class="mi">1</span><span class="o">-&gt;</span><span class="n">intel_iommu_enable_pasid</span> <span class="c1">//1.使能pasid</span>
        		 <span class="mi">2</span><span class="o">-&gt;</span><span class="n">ioasid_alloc</span> <span class="c1">//申请pasid</span>
        		 <span class="mi">3</span><span class="o">-&gt;</span><span class="n">mmu_notifier_register</span> <span class="c1">//注册mmu通知链，处理页表变化支持flush操作</span>
        		 <span class="mi">4</span><span class="o">-&gt;</span><span class="n">intel_pasid_setup_first_level</span><span class="p">(</span><span class="n">iommu</span><span class="p">,</span> <span class="n">dev</span><span class="p">,</span> <span class="n">pgd</span><span class="p">,</span> <span class="n">pasid</span><span class="p">,</span> <span class="n">did</span><span class="p">,</span> <span class="n">flags</span><span class="p">)</span> <span class="c1">//将进程pgd设置到pasid的第一级页表中</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
</pre></td><td class="rouge-code"><pre><span class="c1">//处理pagefault</span>
<span class="n">init_dmars</span> <span class="c1">//intel iommu probe</span>
    <span class="o">+-&gt;</span><span class="n">intel_svm_enable_prq</span> <span class="c1">//CONFIG_INTEL_IOMMU_SVM=y &amp;&amp; 支持pasid &amp;&amp; 支持 prs  page request support</span>
    	<span class="o">+-&gt;</span><span class="n">thread_create</span><span class="p">(</span><span class="n">prq_event_thread</span><span class="p">)</span> <span class="c1">//dmar%d-prq内核线程处理iommu的page fault事件</span>
    		<span class="o">+-&gt;</span><span class="mi">1</span> <span class="n">ioasid_find</span><span class="p">(</span><span class="n">pasid</span><span class="p">)</span> <span class="c1">//从pasid获取svm</span>
    		 <span class="o">-&gt;</span><span class="mi">2</span> <span class="n">find_extend_vma</span><span class="p">(</span><span class="n">svm</span><span class="o">-&gt;</span><span class="n">mm</span><span class="p">,</span> <span class="n">addr</span><span class="p">)</span> <span class="c1">//从mm和addr获取vma</span>
    		 <span class="o">-&gt;</span><span class="mi">3</span> <span class="n">handle_mm_fault</span><span class="p">(</span><span class="n">vma</span><span class="p">,</span> <span class="n">addr</span><span class="p">,</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span><span class="c1">//处理pagefault</span>
</pre></td></tr></tbody></table></code></div></div>

<p>Extended Capability Register: 《vt-directed-io-spec.pdf 》11.4.3 Extended Capability Register</p>

</div>

<div class="post-tail-wrapper text-muted">

  <!-- categories -->
  
  <div class="post-meta mb-3">
    <i class="far fa-folder-open fa-fw me-1"></i>
    
      <a href='/categories/linux/'>linux</a>,
      <a href='/categories/iommu/'>IOMMU</a>
  </div>
  
  <!-- post.html -->

  <!-- tags -->
  
  <div class="post-tags">
    <i class="fa fa-tags fa-fw me-1"></i>
      
      <a href="/tags/iommu/"
          class="post-tag no-text-decoration" >IOMMU</a>
      
  </div>
  
  
  <div class="post-tail-bottom
    d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
    <div class="license-wrapper">

      

        

        This post is licensed under 
        <a href="https://creativecommons.org/licenses/by/4.0/">
          CC BY 4.0
        </a>
         by the author.

      
    </div>

    <!-- Post sharing snippet -->

<div class="share-wrapper">
  <span class="share-label text-muted me-1">Share</span>
  <span class="share-icons">
    
    
    

    
      
      <a
        href="https://twitter.com/intent/tweet?text=Input-Output%20Memory%20Management%20Unit%20-%20Cheng%20Luo&url=https%3A%2F%2Fluochenglcs.github.io%2Fposts%2Flinux-iommu%2F"
        data-bs-toggle="tooltip"
        data-bs-placement="top"
        title="Twitter"
        target="_blank"
        rel="noopener"
        aria-label="Twitter"
      >
        <i class="fa-fw fab fa-twitter"></i>
      </a>
    
      
      <a
        href="https://www.facebook.com/sharer/sharer.php?title=Input-Output%20Memory%20Management%20Unit%20-%20Cheng%20Luo&u=https%3A%2F%2Fluochenglcs.github.io%2Fposts%2Flinux-iommu%2F"
        data-bs-toggle="tooltip"
        data-bs-placement="top"
        title="Facebook"
        target="_blank"
        rel="noopener"
        aria-label="Facebook"
      >
        <i class="fa-fw fab fa-facebook-square"></i>
      </a>
    
      
      <a
        href="https://t.me/share/url?url=https%3A%2F%2Fluochenglcs.github.io%2Fposts%2Flinux-iommu%2F&text=Input-Output%20Memory%20Management%20Unit%20-%20Cheng%20Luo"
        data-bs-toggle="tooltip"
        data-bs-placement="top"
        title="Telegram"
        target="_blank"
        rel="noopener"
        aria-label="Telegram"
      >
        <i class="fa-fw fab fa-telegram"></i>
      </a>
    

    <i
      id="copy-link"
      class="fa-fw fas fa-link small"
      data-bs-toggle="tooltip"
      data-bs-placement="top"
      title="Copy link"
      data-title-succeed="Link copied successfully!"
    >
    </i>
  </span>
</div>


  </div><!-- .post-tail-bottom -->

</div><!-- div.post-tail-wrapper -->


      
    
      
    </div>
  </div>
  <!-- #core-wrapper -->

  <!-- panel -->
  <div id="panel-wrapper" class="col-xl-3 ps-2 text-muted">
    <div class="access">
      <!-- Get the last 5 posts from lastmod list. -->














  <div id="access-lastmod" class="post">
    <div class="panel-heading">Recently Updated</div>
    <ul class="post-content list-unstyled ps-0 pb-1 ms-1 mt-2">
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/%E5%86%85%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93/">MMDB (memory database)</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/userspace-rcu%E9%94%81/">userspace rcu lock</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/Real-time-operating-system/">Realtime Operating System</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/HUNDSUN-LightOS/">Hundsun Lightos</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/linux-struct-folio/">struct folio</a>
        </li>
      
    </ul>
  </div>
  <!-- #access-lastmod -->


      <!-- The trending tags list -->















  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        



  <div id="access-tags">
    <div class="panel-heading">Trending Tags</div>
    <div class="d-flex flex-wrap mt-3 mb-1 me-3">
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/lock/">lock</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/libumem/">libumem</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/mm/">mm</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/autonuma/">autonuma</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bfs/">BFS</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bus/">Bus</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/caladan/">caladan</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/damon/">damon</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/deep-learning/">Deep Learning</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/dma/">DMA</a>
      
    </div>
  </div>


    </div>

    
      
      



  <div id="toc-wrapper" class="ps-0 pe-4 mb-5">
    <div class="panel-heading ps-3 pt-2 mb-2">Contents</div>
    <nav id="toc"><ul><li>Input-Output Memory Management Unit<ul><li><a href="#一虚拟地址">一、虚拟地址</a><ul><li><a href="#1虚拟地址空间iova-domain">1、虚拟地址空间：iova domain</a><ul><li><a href="#1初始化保留区域">1&gt;初始化保留区域</a></li><li><a href="#2-按iommu_group做iova-domain申请">2&gt; 按iommu_group做iova domain申请</a></li></ul></li><li><a href="#2虚拟地址分配">2、虚拟地址分配：</a><ul><li><a href="#1-alloc_iova">1&gt; alloc_iova</a></li><li><a href="#2-free_iova">2&gt; free_iova</a></li><li><a href="#3-split_and_remove_iova">3&gt; split_and_remove_iova</a></li></ul></li></ul></li><li><a href="#二逻辑映射iova_to_phys">二、逻辑映射iova_to_phys</a><ul><li><a href="#1smmu">1、SMMU</a></li><li><a href="#2intel-iommu">2、intel IOMMU:</a></li></ul></li><li><a href="#三smmu与intel-iommu的页表管理">三、SMMU与Intel IOMMU的页表管理</a><ul><li><a href="#1smmu的页表">1、SMMU的页表：</a><ul><li><a href="#1map-页表">1、map 页表</a></li><li><a href="#2tlb-flush函数">2、TLB flush函数</a></li></ul></li><li><a href="#2intel-iommu-1">2、intel IOMMU:</a><ul><li><a href="#1map页表">1、map页表</a></li><li><a href="#2flush-tlb">2、flush tlb</a></li></ul></li><li><a href="#3amd-iommu">3、amd iommu</a></li></ul></li><li><a href="#四-ats">四、 ATS</a><ul><li><a href="#1ats机制想要解决的问题">1、ATS机制想要解决的问题</a></li><li><a href="#2地址翻译过程">2、地址翻译过程</a></li></ul></li><li><a href="#五昇腾smmu和mmu共页表">五、昇腾SMMU和MMU共页表？</a><ul><li><a href="#一由amd的sva方案开始">一、由AMD的SVA方案开始</a></li><li><a href="#二推到社区的sva">二、推到社区的SVA</a></li></ul></li></ul></li></ul></li></ul></nav>
  </div>
  


    
  </div>
</div>

<!-- tail -->

  <div class="row">
    <div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 px-3 pe-xl-4 mt-5">
      
        
        <!--
  Recommend the other 3 posts according to the tags and categories of the current post,
  if the number is not enough, use the other latest posts to supplement.
-->

<!-- The total size of related posts -->


<!-- An random integer that bigger than 0 -->


<!-- Equals to TAG_SCORE / {max_categories_hierarchy} -->








  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  
    
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  






<!-- Fill with the other newlest posts -->





  <div id="related-posts" class="mb-2 mb-sm-4">
    <h3 class="pt-2 mb-4 ms-1" data-toc-skip>
      Further Reading
    </h3>
    <div class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4 mb-4">
      
        
        
        <div class="col">
          <a href="/posts/linux-kcsan/" class="card post-preview h-100">
            <div class="card-body">
              <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class="small"
  data-ts="1599782400"
  data-df="ll"
  
>
  Sep 11, 2020
</em>

              <h4 class="pt-0 my-2" data-toc-skip>The Kernel Concurrency Sanitizer (KCSAN)</h4>
              <div class="text-muted small">
                <p>
                  





                  1 kcasan

2 使用

                </p>
              </div>
            </div>
          </a>
        </div>
      
        
        
        <div class="col">
          <a href="/posts/linux-kprobe/" class="card post-preview h-100">
            <div class="card-body">
              <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class="small"
  data-ts="1600041600"
  data-df="ll"
  
>
  Sep 14, 2020
</em>

              <h4 class="pt-0 my-2" data-toc-skip>Kernel Probe (kprobe)</h4>
              <div class="text-muted small">
                <p>
                  





                  1 kprobe

2 debugfs kprobe trace
kprobe trace 使用debugfs的trace功能
 p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS]  : Set a probe
 r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS]  : Set a r...
                </p>
              </div>
            </div>
          </a>
        </div>
      
        
        
        <div class="col">
          <a href="/posts/linux-userfaultfd/" class="card post-preview h-100">
            <div class="card-body">
              <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class="small"
  data-ts="1600905600"
  data-df="ll"
  
>
  Sep 24, 2020
</em>

              <h4 class="pt-0 my-2" data-toc-skip>Kernel userfaultfd</h4>
              <div class="text-muted small">
                <p>
                  





                  Userfault只支持匿名页，hugetlb、共享内存；

一、软件流程

1 初始化
调用__NR_userfaultfd syscall初始化
调用syscall初始化建立匿名inode文件，并初始化file-&amp;gt;private_data,并返回用户态文件fd。


  
    用户态：

    uffd = syscall(__NR_userfaultfd, O_CLOEXE...
                </p>
              </div>
            </div>
          </a>
        </div>
      
    </div>
    <!-- .card-deck -->
  </div>
  <!-- #related-posts -->


      
        
        <!-- Navigation buttons at the bottom of the post. -->

<div class="post-navigation d-flex justify-content-between">
  
    <a
      href="/posts/linux-autonuma/"
      class="btn btn-outline-primary"
      prompt="Older"
    >
      <p>Kenrel autonuma</p>
    </a>
  

  
    <a
      href="/posts/Deep-Learning-Basics/"
      class="btn btn-outline-primary"
      prompt="Newer"
    >
      <p>Deep Learning Basics</p>
    </a>
  
</div>

      
        
        <!--  The comments switcher -->


      
    </div>
  </div>


        <!-- The Search results -->

<div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
  <div class="col-11 post-content">
    <div id="search-hints">
      <!-- The trending tags list -->















  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        



  <div id="access-tags">
    <div class="panel-heading">Trending Tags</div>
    <div class="d-flex flex-wrap mt-3 mb-1 me-3">
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/lock/">lock</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/libumem/">libumem</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/mm/">mm</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/autonuma/">autonuma</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bfs/">BFS</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bus/">Bus</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/caladan/">caladan</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/damon/">damon</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/deep-learning/">Deep Learning</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/dma/">DMA</a>
      
    </div>
  </div>


    </div>
    <div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
  </div>
</div>

      </div>
    </div>

    <!-- The Footer -->

<footer>
  <div class="container px-lg-4">
    <div class="d-flex justify-content-center align-items-center text-muted mx-md-3">
      <p>Using the <a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a> theme <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
      </p>

      <p>©
        2023
        <a href="https://gitee.com/luochenglcs">luochunsheng</a>.
        
          <span
            data-bs-toggle="tooltip"
            data-bs-placement="top"
            title="Except where otherwise noted, the blog posts on this site are licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author."
          >Some rights reserved.</span>
        
      </p>
    </div>
  </div>
</footer>


    <div id="mask"></div>

    <button id="back-to-top" aria-label="back-to-top" class="btn btn-lg btn-box-shadow">
      <i class="fas fa-angle-up"></i>
    </button>

    
      <div
        id="notification"
        class="toast"
        role="alert"
        aria-live="assertive"
        aria-atomic="true"
        data-bs-animation="true"
        data-bs-autohide="false"
      >
        <div class="toast-header">
          <button
            type="button"
            class="btn-close ms-auto"
            data-bs-dismiss="toast"
            aria-label="Close"
          ></button>
        </div>
        <div class="toast-body text-center pt-0">
          <p class="px-2 mb-3">A new version of content is available.</p>
          <button type="button" class="btn btn-primary" aria-label="Update">
            Update
          </button>
        </div>
      </div>
    

    <!-- JS selector for site. -->

<!-- commons -->



<!-- layout specified -->


  

  
    <!-- image lazy-loading & popup & clipboard -->
    
  















  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  



  <script src="https://cdn.jsdelivr.net/combine/npm/jquery@3.7.0/dist/jquery.min.js,npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js,npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js,npm/lazysizes@5.3.2/lazysizes.min.js,npm/magnific-popup@1.1.0/dist/jquery.magnific-popup.min.js,npm/clipboard@2.0.11/dist/clipboard.min.js,npm/dayjs@1.11.7/dayjs.min.js,npm/dayjs@1.11.7/locale/en.min.js,npm/dayjs@1.11.7/plugin/relativeTime.min.js,npm/dayjs@1.11.7/plugin/localizedFormat.min.js,npm/tocbot@4.21.0/dist/tocbot.min.js"></script>






<script defer src="/assets/js/dist/post.min.js"></script>






    

    <!--
  Jekyll Simple Search loader
  See: <https://github.com/christian-fei/Simple-Jekyll-Search>
-->





<script>
  /* Note: dependent library will be loaded in `js-selector.html` */
  SimpleJekyllSearch({
    searchInput: document.getElementById('search-input'),
    resultsContainer: document.getElementById('search-results'),
    json: '/assets/js/data/search.json',
    searchResultTemplate: '<div class="px-1 px-sm-2 px-lg-4 px-xl-0">  <a href="{url}">{title}</a>  <div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1">    {categories}    {tags}  </div>  <p>{snippet}</p></div>',
    noResultsText: '<p class="mt-5"></p>',
    templateMiddleware: function(prop, value, template) {
      if (prop === 'categories') {
        if (value === '') {
          return `${value}`;
        } else {
          return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`;
        }
      }

      if (prop === 'tags') {
        if (value === '') {
          return `${value}`;
        } else {
          return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`;
        }
      }
    }
  });
</script>

  </body>
</html>

